#include "HiFileTransfer.h"
#include "HiFileReceiverServer.h"
#include "HiFileSender.h"

HiFileTransfer::HiFileTransfer(QObject* parent)
	: QObject(parent)
{
	mReceiverServer = new HiFileReceiverServer(this);
	connect(mReceiverServer, &HiFileReceiverServer::signalReceiveDataSize, this, &HiFileTransfer::signalReceiveDataSize);
	connect(mReceiverServer, &HiFileReceiverServer::signalFileReceiveFinished, this, &HiFileTransfer::signalFileReceiveFinished);
	connect(mReceiverServer, &HiFileReceiverServer::signalReceiveStart, this, &HiFileTransfer::signalReceiveStart);
	connect(mReceiverServer, &HiFileReceiverServer::signalReceiveError, this, &HiFileTransfer::signalReceiveError);
}

HiFileTransfer::~HiFileTransfer()
{
	delete mReceiverServer;
	stopAll();
}

void HiFileTransfer::setSavePaths(const QStringList& paths)
{
	mReceiverServer->setSavePaths(paths);
}

void HiFileTransfer::setMinRemainSize(qint64 size)
{
	mReceiverServer->setMinReaminSize(size);
}

bool HiFileTransfer::startReceiverServer(int port)
{
	return mReceiverServer->listen(QHostAddress::Any, port);
}

void HiFileTransfer::sendFiles(const QString& ip, const QList<HiFileTransferDef::sFile>& files)
{
	HiFileSender* fileSender = nullptr;
	if (!mIpAndSenderMap.contains(ip))
	{
		fileSender = getFileSenderManager()->createSender(ip, mReceiverServer->serverPort());
		connect(fileSender, &HiFileSender::signalSendError, this, [=](const QString& error) {
			emit signalSendError(ip, error);
			});
		connect(fileSender, &HiFileSender::signalSendChanged, this, [=](const HiFileTransferDef::sFile& file) {
			emit signalSendChanged(ip, file);
			});
		connect(fileSender, &HiFileSender::signalSendFinished, this, [=](const HiFileTransferDef::sFile& file) {
			emit signalSendFinished(ip, file);
			});
		connect(fileSender, &HiFileSender::signalSendPrograss, this, [=](const qint64 totalSize, const qint64 size) {
			emit signalSendPrograss(ip, totalSize, size);
			});
		connect(fileSender, &HiFileSender::signalSendAllFinished, this, [=]() {
			emit signalSendAllFinished(ip);
			});
		connect(fileSender, &HiFileSender::signalClose, this, [=]() {
			mIpAndSenderMap.remove(ip);
			getFileSenderManager()->destroySender(fileSender);
			});
		mIpAndSenderMap.insert(ip, fileSender);
	}
	else
	{
		fileSender = mIpAndSenderMap.value(ip);
	}
	fileSender->send(files);
}

void HiFileTransfer::stop(const QString& ip)
{
	HiFileSender* fileSender = mIpAndSenderMap.value(ip);
	if (fileSender)
    {
        fileSender->stop();
		emit signalSendStop(ip);
    }
}

void HiFileTransfer::stopAll()
{
	QMap<QString, HiFileSender*> ipAndSenderMap = mIpAndSenderMap;
	for (auto itr = ipAndSenderMap.begin(); itr != ipAndSenderMap.end(); ++itr)
	{
		itr.value()->stop();
		emit signalSendStop(itr.key());
	}
}